#ifndef GAME_RENDER_H
#define GAME_RENDER_H
#include "game_platform.h"
#include "game_math.h"
#include "game_entity.h"

#define SPRITE_BARRIER_OFFSET_VALUE 0xFFFF

struct sprite_bound {
    manual_sort_key ManualSort;
    real32 YMin;
    real32 YMax;
    real32 ZMax;
    int32 ChunkZ;
};

struct sprite_edge {
    sprite_edge *NextEdgeWithSameFront;
    uint32 Front;
    uint32 Behind;
};

enum sort_flag {
    Sprite_Visited = 0x10000000,
    sprite_Drawn = 0x20000000,
    Sprite_DebugBox = 0x40000000,
    Sprite_Cycle = 0x8000000,
    Sprite_IndexMask = 0x0FFFFFFF,
    Sprite_BarrierTurnsOffSorting = 0xFFFF0000,
};

struct sort_sprite_bound {
    //
    sprite_edge *FirstEdgeWithMeAsFront;
    rectangle2 ScreenArea;
    sprite_bound SortKey;
    uint32 Offset;
    uint32 Flags;
};

struct game_render_prep {
    struct render_entry_cliprect *ClipRects;
    uint32 SortedIndexCount;
    uint32 *SortedIndices;
};

struct camera_params {
    real32 WidthOfMonitor;
    real32 MetersToPixels;
    real32 FocalLength;
};
inline camera_params GetStandardCameraParams(uint32 WidthInPixels, real32 FocalLength) {
    camera_params Result;
    Result.WidthOfMonitor = 0.635f;
    Result.MetersToPixels = (real32)WidthInPixels / Result.WidthOfMonitor;
    Result.FocalLength = FocalLength;
    return Result;
}
void RenderCommandsToBitmap(game_render_commands *Commands, game_render_prep *Prep,
                            loaded_bitmap *OutputTarget, rectangle2i BaseClipRect);
void SoftwareRenderCommands(platform_work_queue *RenderQueue, game_render_commands *Commands,
                            game_render_prep *Prep, loaded_bitmap *OutputTarget,
                            memory_arena *TempArena);
game_render_prep PrepForRender(game_render_commands *Commands, memory_arena *TempArena);
sort_sprite_bound *GetSortEntries(game_render_commands *Commands);
rectangle2i AspectRatioFit(uint32 RenderWidth, uint32 RenderHeight,  //
                           uint32 WindowWidth, uint32 WindowHeight);
#endif